package org.aeon.service;

import org.aeon.dao.BookDao
import org.aeon.dao.UserBorrowBookDao
import org.aeon.entity.Book
import org.aeon.entity.User
import org.aeon.entity.UserBorrowBook
import java.text.SimpleDateFormat
import java.util.*

/**
 * @author: MissingAeon
 * @date: 2024/1/18 16:55
 * @description: 图书服务
 */
class BookService {
    private val bookDao: BookDao = BookDao()
    private val ubbDao: UserBorrowBookDao = UserBorrowBookDao()

    companion object {
        val prompt = {
            println(
                """
            请按下列选项选择需要的操作:
            添加图书...请输入 1
            查询图书...请输入 2
            修改图书...请输入 3
            借阅图书...请输入 4
            查询已经借阅的图书...请输入 5
            退还图书...请输入 6
            退出当前账号...请输入 7
            """.trimIndent()
            )
        }
    }

    // 添加图书
    fun addBooks() {
        do {
            println("添加图书：")
            println("请输入书名:")
            val title = readln()
            println("请输入作者:")
            val author = readln()
            println("请输入单价:")
            val price = readln().toFloat()
            val book = Book(
                "1%04d".format(bookDao.count() + 1), title, author, price
            )
            if (bookDao.insert(book)) println("图书添加成功!")
            else println("图书添加失败！")
            println("按任意键继续添加图书，输入 no 返回主菜单")
            val flag = readln().trim().lowercase() != "no"
        } while (flag)
    }

    // 查询图书
    fun searchBooks() {
        println("查询图书：")
        val books = bookDao.query { true }
        books.forEach { println(it) }
    }

    fun followUp(): (() -> Unit)? {
        println(
            """
        请选择操作:
        修改图书...请输入 1
        删除图书...请输入 2
        返回上一级...请输入 3
        """.trimIndent()
        )
        return when (readln().toInt()) {
            1 -> {
                { modifyBooks() }
            }

            2 -> {
                { delBooks() }
            }

            3 -> null

            else -> {
                { throw IllegalArgumentException() }
            }
        }
    }

    // 修改图书
    fun modifyBooks() {
        println("请输入要修改的图书编号:")
        val bookId = readln().trim()
        if (bookDao.exist(bookId)) {
            val book: Book = bookDao.queryById(bookId)!!
            println(book)
            println("1.修改图书名称2.修改作者 3.修改单价 4. 退出修改")
            when (readln().toInt()) {
                1 -> {
                    print("请输入新的书名：")
                    book.title = readln().trim()
                }

                2 -> {
                    print("请输入新的作者：")
                    book.author = readln().trim()
                }

                3 -> {
                    print("请输入新的单价：")
                    book.price = readln().toFloat()
                }

                4 -> return
            }
            if (bookDao.modify(book)) {
                println("修改成功！")
            }
        }
    }

    // 借阅图书
    fun borrowBooks(user: User) {
        println("请输入要借阅的图书的编号:")
        val bookId = readln().trim()
        if (bookDao.exist(bookId)) {
            val book = bookDao.queryById(bookId)
            println("你要借阅的图书信息:\n$book")
            // 判断该书本是否已被该用户借阅
            if (ubbDao.query {
                    it.user == user.username && it.book == bookId && !it.refund
                }.isNotEmpty()) {
                println("该书您未归还，请归还后再借阅！")
                return
            } else {
                if (ubbDao.insert(UserBorrowBook((ubbDao.count() + 1).toString(), user.username, bookId, Date()))) {
                    println("借阅图书成功")
                } else println("借阅图书失败")
            }
        } else {
            println("该书不存在！")
        }
        println("任意键确认...")
        readln()
    }

    // 查询已经借阅的图书
    fun borrowed(user: User) {
        val bookList = ubbDao.query {
            it.user == user.username
        }
        if (bookList.isEmpty()) {
            println("您当前未借阅！")
            return
        }
        println("您当前的借阅如下:")
        // 排序
        bookList.sortedWith { a, b ->
            if (a.refund xor b.refund) {
                return@sortedWith if (a.refund) 1 else -1
            }
            if (a.date.after(b.date)) 1 else -1
        }.forEach { (_, _, book, date, refund) ->
            val row = "%3s\t%-11s\t%5s\t\t%11s".format(
                book,
                "《${bookDao.queryById(book)?.title ?: "已下架"}》",
                if (refund) "已归还" else "未归还",
                SimpleDateFormat("HH:mm:ss").format(date),
            )
            println(row)
        }
    }

    // 退还图书
    fun returnBook(user: User) {
        do {
            println("请输入要归还的图书编号:")
            val bookId = readln().trim()
            if (bookDao.exist(bookId)) {
                val book = bookDao.queryById(bookId)
                println("要归还的图书信息为：:\n$book")
            }
            println("重选R,退出选择Q,任意键确认归还...")
            when (readln().trim().uppercase()) {
                "R" -> continue
                "Q" -> return
                else -> {
                    val borrowBooks = ubbDao.query {
                        it.user == user.username && it.book == bookId && !it.refund
                    }
                    if (borrowBooks.isNotEmpty()) {
                        val borrowBook = borrowBooks[0]
                        borrowBook.refund = true
                        ubbDao.modify(borrowBook)
                        println("归还图书成功!")
                    } else println("你未借阅该书本！")
                    return
                }
            }
        } while (true)
    }

    // 删除图书
    private fun delBooks() {
        println("请输入要删除的图书编号:")
        val bookId = readln().trim()
        if (bookDao.exist(bookId)) {
            val book = bookDao.queryById(bookId)!!
            println("确认删除《${book.title}》(y/n)？")
            if (readln().trim().lowercase() == "y") {
                if (bookDao.remove(book)) {
                    println("删除成功！")
                } else println("删除失败！")
            }
        } else {
            println("该编号的书名不存在！")
        }
    }
}
